<template>
  <div class="view-announcement">
    <el-button text :bg="isShow" :type="isShow ? 'primary' : ''" @click="handleClick">
      查看公告
    </el-button>
    <el-dialog v-model="viewAnnouncement" width="600" draggable :modal="false">
      <template #header>
        <div class="my-header">
          <h2>公告信息</h2>
        </div>
      </template>
      <section class="announcement-content">
        <div class="time">
          <aside class="title">公告发布时间：</aside>
          <div class="value">
            {{ announcement.time || '暂无' }}
          </div>
        </div>
        <div class="content">
          <aside class="title">公告发布内容：</aside>
          <div class="value">
            {{ announcement.content || '暂无' }}
          </div>
        </div>
      </section>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import { generateUniqueRGBColors } from '@/utils/toolsFn'
import { getAnnouncement } from '@/api/announcement'
import { ElMessageBox } from 'element-plus'

const { map } = defineProps({
  map: {
    type: Object,
    required: true,
  },
})

const isShow = ref(false) //控制展示公告图层
const viewAnnouncement = ref(false) //控制公告框是否展示
const announcement = ref({})
const features = ref([])

const isEmpty = computed(() => features.value.length === 0) //判断announcmentLayer是否为空对象

const view = map.getView()
const announcementLayer = new ol.layer.Vector()
const announcementSource = new ol.source.Vector({})
announcementLayer.setSource(announcementSource)
const geoJSONFormat = new ol.format.GeoJSON()

const handleClick = () => {
  isShow.value = !isShow.value //切换公告图层显示状态
  if (!isShow.value) viewAnnouncement.value = false //关闭公告框
}

watch(isShow, async (val) => {
  if (val) {
    try {
      const {
        data: { geojson },
      } = await getAnnouncement() //获取geojson FeatureCollection字符串
      features.value = geoJSONFormat.readFeatures(geojson) //解析features字符
      if (isEmpty.value) return //空时不尝试添加公告图层
      // 为每个feature设置样式
      const count = features.value.length
      const colors = generateUniqueRGBColors(count)
      features.value.forEach((f, index) => {
        const color = colors[index]
        f.setStyle(
          new ol.style.Style({
            fill: new ol.style.Fill({
              color,
            }),
            stroke: new ol.style.Stroke({
              color: '#333',
              width: 1,
            }),
          }),
        )
      })
      announcementSource.addFeatures(features.value)
      viewAnnouncement.value = true //打开公告框
    } catch {
      ElMessageBox.alert('公告加载失败', {
        type: 'error',
      })
    }
    map.addLayer(announcementLayer)
  } else {
    features.value = [] //清空features
    announcementSource.clear() //清除source中的features
    map.removeLayer(announcementLayer) //移除公告图层
  }
})
watch(viewAnnouncement, () => {
  if (viewAnnouncement.value) {
    const center = view.getCenter()
    const turfPoint = turf.point(center)
    // 遍历features,判断点在哪个多边形内
    features.value.forEach((f) => {
      const geometry = f.getGeometry()
      const coordinates = geometry.getCoordinates()
      const turfPolygon = turf.polygon(coordinates)
      if (turf.booleanPointInPolygon(turfPoint, turfPolygon)) {
        ;({ announcement: announcement.value } = f.getProperties()['values_']) //f.getProperties()获得对象的属性变成了普通js属性
      }
    })
  } else {
    announcement.value = {}
  }
})
</script>

<style lang="scss" scoped>
.view-announcement {
  :deep(.el-dialog) {
    .el-dialog__header {
      border-bottom: 2px solid #eee;
    }
    .el-dialog__body {
      min-height: 5rem;
    }
    .my-header {
      font-size: 1.5rem;
      color: #666;
      font-weight: 600;
    }
    .announcement-content {
      display: grid;
      gap: 1rem;
      margin-top: 1rem;

      .time,
      .content {
        display: flex;
        .title {
          flex: 0 0 content;
          margin-right: 1rem;
          font-weight: 600;
        }
      }
    }
  }
}
</style>
